package be.kuleuven.cs.mop.domain.model.impl;


import java.util.Calendar;

import be.kuleuven.cs.mop.domain.exceptions.TaskManagerException;
import be.kuleuven.cs.mop.domain.model.Task;



/**
 * Representation of a Schedule for a {@link Task}
 */
public class Schedule implements Comparable<Schedule> {
	
	private Calendar	deadline, startDate;
	private long		duration;
	
	/**
	 * Creates a schedule
	 * @param startDate - a start date
	 * @param deadline - a deadline
	 * @param duration - a duration
	 * @throws TaskManagerException INVALID_SCHEDULE_PARAMETERS - Invalid schedule information
	 */
	public Schedule(final Calendar startDate, final Calendar deadline,
			final long duration) throws TaskManagerException {
		if (!isValidSchedule(startDate, deadline, duration))
			throw new TaskManagerException(
					TaskManagerException.INVALID_SCHEDULE_PARAMETERS);
		this.startDate	= startDate;
		this.deadline	= deadline;
		this.duration	= duration;
	}
	
	
	@Override
	public int compareTo(final Schedule schedule) {
		int r = deadline.compareTo(schedule.deadline);
		if (r != 0)
			return r;
		r = startDate.compareTo(schedule.startDate);
		if (r != 0)
			return r;
		return (int)(duration - schedule.duration);
	}
	
	/**
	 * Determines whether or not the specified date falls within this {@link Schedule}
	 * @param date - a <code>Calendar</code>
	 */
	public boolean covers(final Calendar date) {
		return (!date.before(getStartDate()) && !date.after(getDeadline()));
	}
	
	
	public Calendar getDeadline() { return deadline; }
	
	
	public long getDuration() { return duration; }
	
	
	
	
	public Calendar getStartDate() { return startDate; }
	
	
	@Override
	public String toString() {
		return String.format("%s  -  %s  (%s)",
				getStartDate().getTime(),
				getDeadline().getTime(),
				getDuration());
	}
	
	/**
	 * Validates the constructor parameters
	 */
	public static boolean isValidSchedule(final Calendar startDate, final Calendar deadline,
			final long duration) {
		if (startDate == null)
			return false;
		if (deadline == null)
			return false;
		if (duration < 60000)
			return false;
		return deadline.after(startDate);
	}
	
}